package com.binc.testspring.study.nio.netty.simple;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * FileName: My_server_handler   自定义的服务端handler     继承netty的ChannelInboundHandlerAdapter
 *      需要继承netty 规定好的某个HandlerAdapter(规范), 这时我们自定义一个Handler , 才能称为一个handler
 * Autho: binC
 * Date:  2022/4/19 14:49
 */
@Slf4j
public class My_server_handler extends ChannelInboundHandlerAdapter {

    /**
     * 读取数据事件(这里我们可以读取客户端发送的消息)
     *
     *     1. ChannelHandlerContext ctx:上下文对象, 含有 管道pipeline , 通道channel, 地址
     *     2. Object msg: 就是客户端发送的数据 默认Object
     *
     * @param ctx  上下文   这里能获取到 pipeline   也能获取到channel
     * @param msg  真正的消息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // super.channelRead(ctx, msg);

        log.info("<<<<<<=====服务器端读取线程:"+Thread.currentThread().getName()+" channel:"+ctx.channel());
        log.info("<<<<<<=====服务器端  上下文ctx:"+ctx);
        Channel channel = ctx.channel();
        ChannelPipeline pipeline = ctx.pipeline();

        //将msg转成byteBuffer  这个bytebuf 不是nio的,是netty重新封装过的
        ByteBuf buf = (ByteBuf) msg;
        log.info("<<<<<<=====客户端发送的消息是:{}",buf.toString(CharsetUtil.UTF_8));
        log.info("<<<<<<=====客户端的地址是{}",channel.remoteAddress());
        log.info("===========================================================================");

    }

    /**
     * 数据读取完毕
     * @param ctx
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // super.channelReadComplete(ctx);

        //  我们模拟读取完消息后,要给客户端回一个消息
        //writeAndFlush 是 write + flush
        //将数据写入到缓存，并刷新
        //一般讲，我们对这个发送的数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("客户端你好,你的消息我收到了",CharsetUtil.UTF_8));
    }

    /**
     *发生异常的话,关闭通道
     * @param ctx
     * @param cause
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // super.exceptionCaught(ctx, cause);
        ctx.close();
    }
}
